package com.uva.pgpi.sgcc.web.servlets;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Iterator;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import com.uva.pgpi.sgcc.beans.Artefacto;
import com.uva.pgpi.sgcc.beans.Estado;
import com.uva.pgpi.sgcc.beans.Historico;
import com.uva.pgpi.sgcc.beans.Proyecto;
import com.uva.pgpi.sgcc.beans.Solicitud;
import com.uva.pgpi.sgcc.beans.Usuario;
import com.uva.pgpi.sgcc.util.DataBaseConnection;
import com.uva.pgpi.sgcc.util.DateUtils;

/**
 * Servlet implementation class ServletNuevaSolicitud
 */
public class ServletSolicitudes extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public ServletSolicitudes() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String idSolicitud = request.getParameter("id");
		if (idSolicitud != null && !idSolicitud.equals("")) {
			viewSolicitud(request, response);
		} else {
			RequestDispatcher dispatcher = getServletContext()
					.getRequestDispatcher(
							"/ServletRedir?redirigir=mainSolicitudes");
			dispatcher.forward(request, response);
		}

	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String htmlFormName = request.getParameter("htmlFormName");
		Solicitud s = (Solicitud) request.getSession().getAttribute(
				"solicitudSeleccionada");

		// Cojo el valor que venga del formulario para el probador y el
		// trabajador
		Object idTrabajador = request.getParameter("trabajadorLista");
		Object idProbador = request.getParameter("probadorLista");
		String accion = "";
		String filtroEstado = "";
		String filtroProyecto = "";

		if (htmlFormName == null) {
			htmlFormName = "";
		}
		if (htmlFormName.equals("actualizarSolicitud")) {
			accion = (String) request.getParameter("accionLista");
		} else if (htmlFormName.equals("filtrar")) {
			filtroEstado = (String) request.getParameter("filtroEstadoLista");
			filtroProyecto = (String) request
					.getParameter("filtroProyectoLista");
			accion = "accionFiltro";
		} else {
			accion = htmlFormName;
		}

		ConnectionSource cs = null;
		try {
			cs = DataBaseConnection.getInstance().getConnection();
			Dao<Solicitud, String> solicitudDAO = DaoManager.createDao(cs,
					Solicitud.class);
			Dao<Estado, String> estadoDAO = DaoManager.createDao(cs,
					Estado.class);
			Dao<Proyecto, String> proyectoDAO = DaoManager.createDao(cs,
					Proyecto.class);

			Dao<Historico, String> historicoDao = DaoManager.createDao(cs,
					Historico.class);

			long fecha = DateUtils.StringToLong((String) request
					.getParameter("fecha"));

			Historico previousHistorico = null;
			
			if (s!= null && s.getIdSolicitud() > 0){
				previousHistorico = historicoDao.queryBuilder()
				.orderBy(Historico.FECHA, false).where()
				.eq(Historico.SOLICITUD, s.getIdSolicitud()).query().get(0);
			}

			Estado oldEstado = (s != null && s.getEstado() != null) ? s
					.getEstado() : null;

			switch (accion) {

			case "accionFiltro":
				request.getSession().setAttribute("filtroEstado",
						estadoDAO.queryForId(filtroEstado + ""));
				request.getSession().setAttribute("filtroProyecto",
						proyectoDAO.queryForId(filtroProyecto + ""));
				break;

			case "upAbrir":
				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO, "Abierto").get(
						0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha,
						previousHistorico);
				break;
			case "upDupRech":
				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO,
						"Duplicado/Rechazado").get(0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha,previousHistorico);
				break;
			case "upMasInfo":
				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO, "+informacion")
						.get(0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha,previousHistorico);
				break;
			case "upCerrar":
				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO, "Cerrado").get(
						0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha, previousHistorico);
				break;
			case "upAsignar":
				// TODO
				// Aqui tengo que cambiar el trabajador y el probador
				Dao<Usuario, String> UsuarioDAO = DaoManager.createDao(cs,
						Usuario.class);

				// Primero cambio el probador
				s.setTrabajador(UsuarioDAO.queryForEq(Usuario.ID_USUARIO,
						idTrabajador).get(0));

				// Ahora cambio el probador
				s.setProbador(UsuarioDAO.queryForEq(Usuario.ID_USUARIO,
						idProbador).get(0));

				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO, "Asignado")
						.get(0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha,previousHistorico);
				break;
			case "upPruebasFalladas":
				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO,
						"Pruebas Falladas").get(0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha,previousHistorico);
				break;
			case "upResolver":
				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO, "Resuelto")
						.get(0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha,previousHistorico);
				break;
			case "upVerificar":
				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO, "Verificado")
						.get(0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha,previousHistorico);
				break;
			case "upActualizar":
				s.setDescripcion((String) request.getParameter("descripcion"));
				s.setEstado(estadoDAO.queryForEq(Estado.ESTADO, "Actualizado")
						.get(0));
				solicitudDAO.update(s);
				this.createHistorico(historicoDao, s, oldEstado, fecha,previousHistorico);
				break;
			default:
				this.nuevaSolicitud(request, response);
				break;

			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {

			if (cs != null && cs.isOpen()) {
				try {
					cs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}

			RequestDispatcher dispatcher = getServletContext()
					.getRequestDispatcher(
							"/WEB-INF/solicitante/mainSolicitante.jsp");
			dispatcher.forward(request, response);
		}

	}

	private void createHistorico(Dao<Historico, String> historicoDao,
			Solicitud s, Estado oldEstado, long fecha, Historico previous)
			throws SQLException {
		historicoDao.create(new Historico(s, oldEstado, s.getEstado(),
				oldEstado.getEstado() + " -> " + s.getEstado().getEstado()
						+ "["
						+ DateUtils.getDuration(fecha - previous.getFecha())
						+ "]", fecha));
	}

	private void viewSolicitud(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		ConnectionSource cs;
		try {
			cs = DataBaseConnection.getInstance().getConnection();
			Dao<Solicitud, String> solicitudDAO = DaoManager.createDao(cs,
					Solicitud.class);

			String idSolicitud = request.getParameter("id");
			Iterator<Solicitud> it = solicitudDAO.queryForEq(
					Solicitud.ID_SOLICITUD, idSolicitud).iterator();
			Solicitud s = null;

			if (it.hasNext())
				s = it.next();
			if (s != null) {
				request.setAttribute("solicitudSeleccionada", s);
				request.getSession().setAttribute("solicitudSeleccionada", s);
				request.setAttribute("id", s.getIdSolicitud());
			}

			cs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			RequestDispatcher dispatcher = getServletContext()
					.getRequestDispatcher(
							"/WEB-INF/solicitante/verSolicitud.jsp");
			dispatcher.forward(request, response);
		}

	}

	private void nuevaSolicitud(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// Obtengo los parametros que vienen del formulario

		Solicitud s = new Solicitud();

		s.setNombre((String) request.getParameter("nombre"));
		s.setDescripcion((String) request.getParameter("descripcion"));

		s.setFecha(DateUtils.StringToLong((String) request
				.getParameter("fecha")));

		Usuario user = (Usuario) request.getSession()
				.getAttribute("loggedUser");
		s.setSolicitante(user);

		// Obtengo el id del artefacto que el usuario haya marcado

		int idArtefacto = Integer.valueOf(request.getParameter("artefacto"));

		// Obtengo el artefacto asociado a ese id

		ConnectionSource conn;
		try {

			conn = DataBaseConnection.getInstance().getConnection();
			Dao<Artefacto, String> ArtefactoDAO = DaoManager.createDao(conn,
					Artefacto.class);

			Iterator<Artefacto> it;

			it = ArtefactoDAO.queryBuilder().where()
					.eq(Artefacto.ID_ARTEFACTO, idArtefacto).query().iterator();

			while (it.hasNext()) {
				s.setArtefacto(it.next());
			}

			// Obtengo el estado, como se acaba de crear va a ser abierto

			Dao<Estado, String> estadoDAO = DaoManager.createDao(conn,
					Estado.class);

			Iterator<Estado> itE;

			itE = estadoDAO.queryBuilder().where().eq(Estado.ESTADO, "Enviado")
					.query().iterator();

			while (itE.hasNext()) {
				s.setEstado(itE.next());
			}

			s.setProbador(user);
			s.setTrabajador(user);

			Dao<Solicitud, String> SolicitudDao = DaoManager.createDao(conn,
					Solicitud.class);
			TableUtils.createTableIfNotExists(conn, Solicitud.class);

			Dao<Historico, String> historicoDao = DaoManager.createDao(conn,
					Historico.class);

			// Creo la tabla por si es la primera solicitud que se crea
			// TableUtils.dropTable(conn, Solicitud.class,true);
			TableUtils.createTableIfNotExists(conn, Historico.class);
			SolicitudDao.create(s);
			long fecha = DateUtils.StringToLong((String) request
					.getParameter("fecha"));
			historicoDao.create(new Historico(SolicitudDao.queryForId(s
					.getIdSolicitud() + ""), s.getEstado(), s.getEstado(),
					" [] " + " -> " + s.getEstado().getEstado(), fecha));
			// this.createHistorico(historicoDao, s, s.getEstado(), fecha);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}

	}

}
